package weeek12.topic02;

import com.alibaba.fastjson.JSON;
import redis.clients.jedis.*;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisApplication {

	public static void main(String[] args) {
		String host = "192.168.75.131";


		simple(host);
		sentinelPool(host);
		sentinelTest(host);
		cluster(host);


	}

	private static void cluster(String host) {
		JedisCluster cluster = getJedisCluster(host);
		for (int i = 0; i < 100; i++) {
			cluster.set("cluster:" + i, "data:" + i);
		}
		System.out.println(cluster.get("cluster:92"));
		cluster.close();
	}

	private static void sentinelTest(String host) {
		// C3. 直接连接sentinel进行操作
		Jedis jedisSentinel = new Jedis(host, 16380); // 连接到sentinel
		List<Map<String, String>> masters = jedisSentinel.sentinelMasters();
		System.out.println(JSON.toJSONString(masters));
		List<Map<String, String>> slaves = jedisSentinel.sentinelSlaves("mymaster");
		System.out.println(JSON.toJSONString(slaves));
	}

	private static void sentinelPool(String host) {
		// C2.基于sentinel和连接池的demo
		JedisSentinelPool pool = SentinelJedisConfig.createJedisSentinelPool(host);
		Jedis sjedis = pool.getResource();
		System.out.println(sjedis.info());
		sjedis.set("uptime2", new Long(System.currentTimeMillis()).toString());
		System.out.println(sjedis.get("uptime2"));
		pool.close();
	}

	private static void simple(String host) {
		// C1.最简单demo
		Jedis jedis = new Jedis(host, 6380);
		System.out.println(jedis.info());
		jedis.set("uptime", new Long(System.currentTimeMillis()).toString());
		System.out.println(jedis.get("uptime"));
		jedis.set("teacher", "Cuijing");
		System.out.println(jedis.get("teacher"));
	}

	private static JedisCluster getJedisCluster(String host) {
		JedisCluster jedisCluster = null;
		// 添加集群的服务节点Set集合
		Set<HostAndPort> hostAndPortsSet = new HashSet<HostAndPort>();
		// 添加节点
		hostAndPortsSet.add(new HostAndPort(host, 6382));
		hostAndPortsSet.add(new HostAndPort(host, 6381));
		hostAndPortsSet.add(new HostAndPort(host, 6380));
		// hostAndPortsSet.add(new HostAndPort("127.0.0.1", 6381));

		// Jedis连接池配置
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		// 最大空闲连接数, 默认8个
		jedisPoolConfig.setMaxIdle(12);
		// 最大连接数, 默认8个
		jedisPoolConfig.setMaxTotal(16);
		//最小空闲连接数, 默认0
		jedisPoolConfig.setMinIdle(4);
		// 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
		jedisPoolConfig.setMaxWaitMillis(2000); // 设置2秒
		//对拿到的connection进行validateObject校验
		jedisPoolConfig.setTestOnBorrow(true);
		jedisCluster = new JedisCluster(hostAndPortsSet, jedisPoolConfig);
		return jedisCluster;
	}

}


class SentinelJedisConfig {

	//可用连接实例的最大数目，默认为8；
	//如果赋值为-1，则表示不限制，如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)
	private static Integer MAX_TOTAL = 16;
	//控制一个pool最多有多少个状态为idle(空闲)的jedis实例，默认值是8
	private static Integer MAX_IDLE = 12;
	//等待可用连接的最大时间，单位是毫秒，默认值为-1，表示永不超时。
	//如果超过等待时间，则直接抛出JedisConnectionException
	private static Integer MAX_WAIT_MILLIS = 10000;
	//客户端超时时间配置
	private static Integer TIMEOUT = 10000;
	//在borrow(用)一个jedis实例时，是否提前进行validate(验证)操作；
	//如果为true，则得到的jedis实例均是可用的
	private static Boolean TEST_ON_BORROW = true;
	//在空闲时检查有效性, 默认false
	private static Boolean TEST_WHILE_IDLE = true;
	//是否进行有效性检查
	private static Boolean TEST_ON_RETURN = true;


	/**
	 * 创建连接池
	 */
	public static JedisSentinelPool createJedisSentinelPool(String host) {
		JedisPoolConfig config = new JedisPoolConfig();
        /*注意：
            在高版本的jedis jar包，比如本版本2.9.0，JedisPoolConfig没有setMaxActive和setMaxWait属性了
            这是因为高版本中官方废弃了此方法，用以下两个属性替换。
            maxActive  ==>  maxTotal
            maxWait==>  maxWaitMillis
         */
		config.setMaxTotal(MAX_TOTAL);
		config.setMaxIdle(MAX_IDLE);
		config.setMaxWaitMillis(MAX_WAIT_MILLIS);
		config.setTestOnBorrow(TEST_ON_BORROW);
		config.setTestWhileIdle(TEST_WHILE_IDLE);
		config.setTestOnReturn(TEST_ON_RETURN);
		String masterName = "mymaster";
		Set<String> sentinels = new HashSet<String>();
		sentinels.add(new HostAndPort(host,26379).toString());
		sentinels.add(new HostAndPort(host,26380).toString());
		JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels, config, TIMEOUT, null);
		return pool;
	}



}